package com.hgh.nettydemo.javanio.javanioserver;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.Iterator;

/**
 * @author: huguanghui
 * Created by huguanghui on 2018/6/18.
 * @Description:
 */
public class JavaNioServer {

    private int port = 8888;
    private ServerSocketChannel serverSocketChannel;
    private Charset charset = Charset.forName("UTF-8");
    private Selector selector = null;


    public void createJavaNioServer() throws IOException {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().setReuseAddress(true);
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务器启动");
        new Thread(new ReceiveThread()).start();
    }


    public class ReceiveThread implements Runnable {

        @Override
        public void run() {

            try {
                while (selector.select() > 0) {
                    Iterator iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = null;
                        try {
                            key = (SelectionKey) iterator.next();
                            iterator.remove();
                            if (key.isAcceptable()) {
                                ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                                SocketChannel sc = ssc.accept();
                                System.out
                                        .println("客户端机子的地址是 "
                                                + sc.socket().getRemoteSocketAddress()
                                                + "  客户端机机子的端口号是 "
                                                + sc.socket().getLocalPort());
                                sc.configureBlocking(false);
                                ByteBuffer buffer = ByteBuffer.allocate(1024);
                                sc.register(selector, SelectionKey.OP_READ,buffer);
                            }
                            if (key.isReadable()) {
                                reveice(key);
                            }
//                            if (key.isWritable()) {
//                                send(key);
//                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            try {
                                if (key != null) {
                                    key.cancel();
                                    key.channel().close();
                                }
                            } catch (ClosedChannelException cex) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        public void reveice(SelectionKey key) throws IOException {
            if (key == null) {
                return;
            }

            SocketChannel sc = (SocketChannel) key.channel();
            ByteArrayOutputStream output=new ByteArrayOutputStream();
            ByteBuffer buffer=ByteBuffer.allocate(1024);
            while(sc.read(buffer) !=0){
                buffer.flip();
                byte[] by = new byte[buffer.remaining()];
                buffer.get(by);
                output.write(by);
                buffer.clear();
            }
            System.out.println(new String(output.toByteArray()));
            output.close();

        }

        public void send(SelectionKey key) {
            if (key == null) {
                return;
            }
            SocketChannel sc = (SocketChannel) key.channel();
            try {
                sc.write(ByteBuffer.wrap(new String("hello china").getBytes()));
            } catch (IOException e1) {
                e1.printStackTrace();
            }

        }

    }
}
